package itsm.isperp.workflow.web.controller;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.domain.DataResponse;
import itsm.isperp.framework.web.request.JqGridRequest;
import itsm.isperp.framework.web.response.ResultMessage;
import itsm.isperp.workflow.service.BpmBpmnModelService;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * 
 * bpmn模型控制器
 * 
 * @author lizx
 * @date 2013-6-26
 * 
 */
@Controller
@RequestMapping(value = "workflow/bpmnModel")
public class ProcessBpmnModelController implements ModelDataJsonConstants {

	@Autowired
	RepositoryService repositoryService;

	@Autowired
	BpmBpmnModelService bpmBpmnModelService;

	@Autowired
	private ObjectMapper objectMapper;

	@RequestMapping("open")
	public ModelAndView editor(
			@RequestParam(value = "id", required = false) String id)
			throws Exception {
		ModelAndView mv = new ModelAndView("workflow/bpmnModel/editor");
		mv.addObject("ctx", ContextHolder.getWebServerName());
		return mv;
	}

	/**
	 * 流程编辑界面
	 * 
	 * @return 流程编辑界面
	 */
	@RequestMapping("edit")
	public ModelAndView edit(String id, HttpServletRequest request,
			RedirectAttributes redirectAttributes) {
		if (StringUtils.isEmpty(id)) {
			ModelAndView mv = new ModelAndView("workflow/process/edit");
			mv.addObject("model", repositoryService.newModel());
			mv.addObject("pageTitle", "添加流程");
			return mv;
		} else {

			redirectAttributes.addAttribute("id", id);
			// 重定向至设计器
			return new ModelAndView(new RedirectView(request.getContextPath()
					+ "/workflow/service/editor"));
		}
	}

	@RequestMapping(value = "{modelId}/save")
	@ResponseBody
	public ResultMessage saveModel(@PathVariable("modelId") String modelId,
			@RequestBody MultiValueMap<String, String> values,
			HttpServletRequest req) throws Exception {
		String name = values.getFirst("name");

		String description = values.getFirst("description");
		String json_xml = values.getFirst("json_xml");
		String svg_xml = values.getFirst("svg_xml");

		Model model = repositoryService.getModel(modelId);

		ObjectNode modelJson = (ObjectNode) objectMapper.readTree(model
				.getMetaInfo());

		modelJson.put(MODEL_NAME, name);
		modelJson.put(MODEL_DESCRIPTION, description);
		model.setMetaInfo(modelJson.toString());
		model.setName(name);

		repositoryService.saveModel(model);

		repositoryService.addModelEditorSource(model.getId(),
				json_xml.getBytes("utf-8"));

		InputStream svgStream = new ByteArrayInputStream(
				svg_xml.getBytes("utf-8"));
		TranscoderInput input = new TranscoderInput(svgStream);

		PNGTranscoder transcoder = new PNGTranscoder();
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		TranscoderOutput output = new TranscoderOutput(outStream);

		transcoder.transcode(input, output);
		final byte[] result = outStream.toByteArray();
		repositoryService.addModelEditorSourceExtra(model.getId(), result);
		outStream.close();
		bpmBpmnModelService.save(name, model.getKey(), description);

		return ResultMessage.success();
	}

	/**
	 * 部署流程
	 * 
	 * @throws Exception
	 */
	@RequestMapping(value = "deploy")
	@ResponseBody
	public ResultMessage deploy(String modelId) throws Exception {
		this.bpmBpmnModelService.deploy(modelId);
		return ResultMessage.success();
	}

	/**
	 * 菜单管理界面s
	 * 
	 * @return 菜单管理界面视图
	 */
	@RequestMapping(value = { "manage", "" })
	public ModelAndView manage(HttpServletRequest req) {
		ModelAndView mv = new ModelAndView("workflow/bpmnModel/manage");
		mv.addObject("pageTitle", "流程管理");
		return mv;
	}

	/**
	 * 模型列表
	 */
	@RequestMapping("list")
	@ResponseBody
	public DataResponse<Model> list(JqGridRequest request,
			HttpServletRequest req) {

		return this.bpmBpmnModelService.findAll(request);

	}

	/**
	 * 导出设计器的xml文件
	 * 
	 * @throws IOException
	 * @throws JsonProcessingException
	 */
	@RequestMapping(value = "export/{modelId}")
	public void export(@PathVariable("modelId") String modelId,
			HttpServletResponse response) throws JsonProcessingException,
			IOException {

		ByteArrayInputStream in = bpmBpmnModelService.export(modelId);
		IOUtils.copy(in, response.getOutputStream());
		response.flushBuffer();

	}
}
